ResManager = BaseClass:Extend()
local CSResMgr = CS.ResMgr
local RES_CACHE_TIME = 0

function ResManager:New()
	local o = ResManager.super.New(self)
	--资源引用计数
	o.dic_res_count = {}            --[abName] = num
	o.dic_res_ref = {}              --[self] = {abName}
	o.loading_ab = {}               --正在加载的ab包 加载前占个坑 防止反复走加载逻辑\
	o.dic_cache_ab = {}             --当前页已经加载的ab
	o.loading_wait_handler = {}     --当前等待的加载
	o.loading_wait_spirit_handler = {} --当前等待的加载
	o:Init()
	return o
end

function ResManager:Init()
	UpdateBeatManager:GetInstance():AddUpdateBeat(self)
end

function ResManager:GetInstance()
	if self.instance == nil then
		self.instance = self:New()
	end
	return self.instance
end

function ResManager:LoadLocalRes(resName, type, func)
	CS.ResLocalManager.Instance:LoadLocalUObjectAsync(resName, type, nil, func)
end

function ResManager:LoadRes(that, abName, resName, level, func)
	CSResMgr.Instance:LoadRes(abName, resName, func, (level or 0))
	self:AddResRef(that, abName)
end

--加载UI/下的资源
function ResManager:LoadSprite(that, img, abName, resName, native, loadfunc)
	if not string.find(abName, "texture") then
		abName = abName .. "_texture"
	end
	local function loaded_callback(obj)
		self:UpdateABResCacheDic(abName, resName, obj)
		obj = CS.Utils.ConvertObjectToSprite(obj)
		self.loading_ab[abName] = false
		if obj then
			if native then
				img:SetNativeSize()
			end
			img.sprite = obj
			if loadfunc then
				loadfunc(obj)
			end
		end
	end

	local cache_obj = self:GetCacheResObj(abName, resName)
	if cache_obj then
		loaded_callback(cache_obj)
	else
		CSResMgr.Instance:LoadSprite(abName, resName, loaded_callback)
		--if not self.loading_ab[abName] then
		--	CSResMgr.Instance:LoadSprite(abName,resName,loaded_callback)
		--	self.loading_ab[abName] = true
		--else
		--	if not self.loading_wait_spirit_handler1[abName] then
		--		self.loading_wait_spirit_handler1[abName] = {func = function(obj)
		--			loaded_callback(obj)
		--		end}
		--	end
		--end
	end
	self:AddResRef(that, abName)
end

--加载Icon/下的资源
function ResManager:LoadOutSideSprite(that, img, module, resName, native, loadfunc)
	if module == nil or module == "" then
		module = "Icon_" .. resName
	else
		module = "Icon_" .. module .. "_" .. resName
	end
	local function loaded_callback(obj)
		self:UpdateABResCacheDic(module, resName, obj)
		obj = CS.Utils.ConvertObjectToSprite(obj)
		self.loading_ab[module] = false
		if obj then
			if native then
				img:SetNativeSize()
			end
			img.sprite = obj
			if loadfunc then
				loadfunc(obj)
			end
		end
	end

	local cache_obj = self:GetCacheResObj(module, resName)
	if cache_obj then
		loaded_callback(cache_obj)
	else
		if not self.loading_ab[module] then
			CSResMgr.Instance:LoadOutSideSprite(module, resName, loaded_callback)
			self.loading_ab[module] = true
		end
	end
	self:AddResRef(that, module)
end

--加载界面预制
function ResManager:CreateView(that, abName, resName, layer, loadUICallback)
	if not string.find(abName, "_prefab") then
		abName = abName .. "_prefab"
	end
	if CS.Const.LOCAL then
		CS.PanelManager.Instance:CreateViewLocal(abName, resName, layer, function(obj)
			self.loading_ab[abName] = false
			loadUICallback(obj)
		end)
		return
	end
	if not self.loading_ab[abName] then
		self.loading_ab[abName] = true
		CS.PanelManager.Instance:CreateView(abName, resName, layer, function(obj)
			self.loading_ab[abName] = false
			loadUICallback(obj)
		end)
	end
	self:AddResRef(that, abName)
end

--加载界面组件
function ResManager:CreateItem(that, abName, resName, loadUICallback)
	if not string.find(abName, "_prefab") then
		abName = abName .. "_prefab"
	end
	if not self.loading_ab[abName] then
		self.loading_ab[abName] = true
		CS.PanelManager.Instance:CreateItem(abName, resName, function(obj)
			self.loading_ab[abName] = false
			if self.loading_wait_handler[abName] and #self.loading_wait_handler[abName] > 0 then
				for i, v in ipairs(self.loading_wait_handler[abName]) do
					v(NewObj(obj))
				end
			end
			self.loading_wait_handler[abName] = false
			loadUICallback(NewObj(obj))
		end)
	else
		self.loading_wait_handler[abName] = self.loading_wait_handler[abName] or {}
		table.insert(self.loading_wait_handler[abName], loadUICallback)
	end
	self:AddResRef(that, abName)
end

--对应引用的计数+1
function ResManager:AddResRef(that, abName)
	self.dic_res_ref[that.__id] = self.dic_res_ref[that.__id] or {}
	if not self.dic_res_ref[that.__id][abName] then
		self.dic_res_count[abName] = self.dic_res_count[abName] and (self.dic_res_count[abName] + 1) or 1
	end
	self.dic_res_ref[that.__id][abName] = true
end

--定时检测销毁
function ResManager:Update(time)
	local curr_time = GetTime()
	for name, vo in pairs(ResManager:GetInstance().dic_cache_ab) do
		if vo.dirty and vo.last_time + RES_CACHE_TIME <= curr_time then
			self:UnloadAB(name)
		end
	end
end

--删除某个实例对应的所有资源引用
function ResManager:ClearAllRef(that)
	local loadedBundles = self.dic_res_ref[that.__id]
	if loadedBundles and next(loadedBundles) then
		for i, v in pairs(loadedBundles) do
			if self.dic_res_count[i] and self.dic_res_count[i] == 1 then
				--CSResMgr.Instance:UnloadRes(i,true)
				self:SetABResDirty(i) --将AB资源设置成脏
			end
			if self.dic_res_count[i] and self.dic_res_count[i] > 1 then
				self.dic_res_count[i] = self.dic_res_count[i] - 1
			end
		end
	end
	if that.__id and self.dic_res_ref[that.__id] then
		self.dic_res_ref[that.__id] = nil
	end
end

--更新某个资源的使用情况
--dic_cache_ab[abname] = {list={res...} ,last_time , dirty}
function ResManager:UpdateABResCacheDic(ab_name, ab_res, obj)
	if self.dic_cache_ab[ab_name] and self.dic_cache_ab[ab_name].list then
		if not self.dic_cache_ab[ab_name].list[ab_res] then
			self.dic_cache_ab[ab_name].list[ab_res] = obj
		end
		self.dic_cache_ab[ab_name].dirty = false
	else
		self.dic_cache_ab[ab_name] = { list = { [ab_res] = obj }, last_time = GetTime(), dirty = false }
	end
end

function ResManager:GetCacheResObj(ab_name, res_name)
	if self.dic_cache_ab[ab_name] and self.dic_cache_ab[ab_name].list[res_name] then
		return self.dic_cache_ab[ab_name].list[res_name]
	end
end

--将某个ab资源设置成脏标识
function ResManager:SetABResDirty(ab_name)
	if self.dic_cache_ab[ab_name] then
		self.dic_cache_ab[ab_name].dirty = true
		self.dic_cache_ab[ab_name].last_time = GetTime()
	else
		self:UnloadAB(ab_name)
	end
	self.dic_res_count[ab_name] = nil
	if self.loading_ab[ab_name] then
		self.loading_ab[ab_name] = nil
	end
end

function ResManager:UnloadAB(ab_name)
	CSResMgr.Instance:UnloadRes(ab_name, true)
	self.dic_cache_ab[ab_name] = nil
end
